(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(['./util'], factory);
  } else if (typeof exports !== "undefined") {
    factory(require('./util'));
  } else {
    var mod = {
      exports: {}
    };
    factory(global.util);
    global.dropwizard = mod.exports;
  }
})(this, function (_util) {
  'use strict';

  var _util2 = _interopRequireDefault(_util);

  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
      default: obj
    };
  }

  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
    return typeof obj;
  } : function (obj) {
    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  };

  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  var _createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

  (function ($) {

    var NAME = 'DROPWIZARD';
    var SEPERATOR = $.zepto ? ':' : '.';
    var DATA_KEY = 'fancy' + SEPERATOR + 'dropwizard';
    var EVENT_KEY = '' + DATA_KEY;

    var BACKDROP_TRANSITION_DURATION = 600;

    var Selector = {
      DATA_TOGGLE: '[data-toggle="dropwizard"]',
      DATA_MENU: '[data-drop-menu]',
      DATA_DIRECT: '[data-direct]',
      DATA_VALUE: '[data-value]'
    };

    var Event = {
      TOGGLE: 'click.toggle.' + EVENT_KEY,
      DIRECT: 'click.direct.' + EVENT_KEY,
      SELECT: 'click.select.' + EVENT_KEY,
      SHOW: 'show' + SEPERATOR + EVENT_KEY,
      SHOWN: 'shown' + SEPERATOR + EVENT_KEY,
      HIDE: 'hide' + SEPERATOR + EVENT_KEY,
      HIDDEN: 'hidden' + SEPERATOR + EVENT_KEY,
      SELECTED: 'selected' + SEPERATOR + EVENT_KEY
    };

    var ClassName = {
      MENU: '.menu',
      SUB_MENU: '.menu.sub'
    };

    var container = $(document.body);

    var Dropwizard = function () {
      function Dropwizard(element, options) {
        _classCallCheck(this, Dropwizard);

        this._element = $(element);
        this._options = options;
        this._wizards = this._element.find(Selector.DATA_TOGGLE);
        this._menus = this._element.find(Selector.DATA_MENU);
        this._backdrop = null;

        this._isTransitioning = false;
        this._isOpened = false;
        this._isSwitching = false;

        this._element.on(Event.TOGGLE, Selector.DATA_TOGGLE, $.proxy(this.toggle, this));
        this._element.on(Event.DIRECT, Selector.DATA_DIRECT, $.proxy(this._direct, this));
        this._element.on(Event.SELECT, Selector.DATA_VALUE, $.proxy(this._select, this));
      }

      _createClass(Dropwizard, [{
        key: 'toggle',
        value: function toggle(event) {
          event.preventDefault();
          var wizard = $(event.currentTarget);
          var isWizardActive = this._isActive(wizard);

          if (!isWizardActive && this._isOpened) {
            this._isSwitching = true;
          }
          isWizardActive ? this._hide(wizard) : this._show(wizard);
          this._isSwitching = false;
        }
      }, {
        key: '_show',
        value: function _show(wizard) {
          var _this = this;

          if (this._isTransitioning) {
            return;
          }

          var e = $.Event(Event.SHOW, { relatedTarget: wizard[0] });
          this._element.trigger(e);
          if (e.isDefaultPrevented()) {
            return;
          }

          var activeWizard = this._getActive();
          if (activeWizard.length) {
            this._hide(activeWizard);
          }

          this._isOpened = true;
          this._isTransitioning = true;

          var complete = function complete() {
            wizard.addClass('active');
            var activeMenu = _this._getTargetMenu(wizard);
            _this._layoutMenu(activeMenu);
            activeMenu.addClass('active');

            _this._isTransitioning = false;
            _this._element.trigger($.Event(Event.SHOWN, { relatedTarget: wizard[0] }));
          };

          if (this._isSwitching) {
            return complete();
          }
          this._toggleBackdrop(complete);
        }
      }, {
        key: '_hide',
        value: function _hide(wizard) {
          var _this2 = this;

          if (this._isTransitioning) {
            return;
          }

          var e = $.Event(Event.HIDDEN, { relatedTarget: wizard[0] });
          this._element.trigger(e);
          if (e.isDefaultPrevented()) {
            return;
          }

          if (!this._isSwitching) {
            this._isOpened = false;
          }
          this._isTransitioning = true;

          wizard.removeClass('active');
          this._getTargetMenu(wizard).removeClass('active');

          var complete = function complete() {
            _this2._isTransitioning = false;
            _this2._element.trigger($.Event(Event.HIDDEN, { relatedTarget: wizard[0] }));
          };

          if (this._isSwitching) {
            return complete();
          }
          this._toggleBackdrop(complete);
        }
      }, {
        key: '_direct',
        value: function _direct(event) {
          event.preventDefault();
          event.stopPropagation();
          event.stopImmediatePropagation();

          var $direct = $(event.currentTarget);
          var $target = $($direct.data('direct'));

          var $menu = $direct.parents(ClassName.MENU);
          var $activeItem = $menu.find('.active');
          if ($activeItem.length) {
            $activeItem.removeClass('active');
            $($activeItem.children(Selector.DATA_DIRECT).data('direct')).removeClass('active');
          }

          $direct.parent().addClass('active');
          $target.addClass('active');
        }
      }, {
        key: '_select',
        value: function _select(event) {
          event.preventDefault();
          event.stopPropagation();
          event.stopImmediatePropagation();

          var $target = $(event.currentTarget);
          if ($target.hasClass('active')) {
            return;
          }

          // let e = $.Event(Event.SELECT, { relatedTarget: $target[0] })
          // this._element.trigger(e)
          // if (e.isDefaultPrevented()) {
          //   return
          // }

          var $targetMenu = $target.parents(Selector.DATA_MENU);
          // let preActive = $targetMenu.data('prev-active')
          // if (preActive) {
          //   $(`[data-value="${preActive}"]`).parent().removeClass('active')
          // }
          $targetMenu.find('.menu .active').each(function (idx, el) {
            var $el = $(el);
            if (!$el.children().data('direct')) {
              $el.removeClass('active');
            }
          });

          $target.parent().addClass('active');
          // $targetMenu.data('prev-active', $target.data('value'))

          var $targetWizard = this._getTargetWizard($targetMenu);
          $targetWizard.children('span').text($target.text().trim());

          this._hide($targetWizard);
          this._element.trigger($.Event(Event.SELECTED, { relatedTarget: $target[0] }));
        }
      }, {
        key: '_toggleBackdrop',
        value: function _toggleBackdrop(callback) {
          var _this3 = this;

          var animate = this._element.hasClass('animate') ? 'animate' : '';
          if (this._isOpened) {

            var doAnimate = _util2.default.supportTransitionEnd() && animate;
            this._backdrop = $(document.createElement('div')).addClass('dropwizard-backdrop').appendTo(container);

            if (doAnimate) {
              _util2.default.reflow(this._backdrop[0]);
            }
            this._backdrop.addClass('in');

            if (!callback) {
              return;
            }

            doAnimate ? this._backdrop.one(_util2.default.transitionEnd(), callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION) : callback();
          } else if (!this._isOpened && this._backdrop) {
            this._backdrop.removeClass('in');

            var complete = function complete() {
              _this3._backdrop && _this3._backdrop.remove();
              _this3._backdrop = null;
              callback && callback();
            };

            if (!_util2.default.supportTransitionEnd() || !this._element.hasClass('animate')) {
              return complete();
            }
            this._backdrop.one(_util2.default.transitionEnd(), complete).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
          } else if (callback) {
            callback();
          }
        }
      }, {
        key: '_layoutMenu',
        value: function _layoutMenu(menu) {
          var submenus = menu.children(ClassName.SUB_MENU);
          if (submenus.length) {
            menu.find(ClassName.MENU).css('width', '45%');
            submenus.css('width', '55%').css('left', '45%');
          }
        }
      }, {
        key: '_getTargetMenu',
        value: function _getTargetMenu(wizard) {
          return $(this._menus.get(wizard.index()));
        }
      }, {
        key: '_getTargetWizard',
        value: function _getTargetWizard(menu) {
          return $(this._wizards.get(menu.index() - 1));
        }
      }, {
        key: '_isActive',
        value: function _isActive(wizard) {
          return wizard.hasClass('active');
        }
      }, {
        key: '_getActive',
        value: function _getActive() {
          return this._element.find(Selector.DATA_TOGGLE).filter('.active');
        }
      }], [{
        key: '_plugin',
        value: function _plugin(option) {
          return this.each(function () {
            var $this = $(this);
            var data = $this.data(DATA_KEY);
            var options = $.extend({}, Dropwizard.Default, $this.data(), (typeof option === 'undefined' ? 'undefined' : _typeof(option)) == 'object' && option);

            if (!data) $this.data(DATA_KEY, data = new Dropwizard(this, options));
            if (typeof option === 'string') data[option]();
          });
        }
      }, {
        key: 'Default',
        get: function get() {}
      }]);

      return Dropwizard;
    }();

    var old = $.fn.dropwizard;
    $.fn.dropwizard = Dropwizard._plugin;
    $.fn.dropwizard.Constructor = Dropwizard;

    // DROPWIZARD NO CONFLICT
    // ======================

    $.fn.dropwizard.noConflict = function () {
      $.fn.dropwizard = old;
      return undefined;
    };
  })(Zepto || jQuery);
});